﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
using System.Reflection; 

namespace PSE.Framework.Service.Validation
{
    /// <summary>
    /// Atributo responsável por comparações entre propriedades (de um mesmo objeto)
    /// Os tipo das propriedades comparadas devem implementar IComparable e devem ser 
    /// compatíveis para efeitos de comparação
    /// </summary>
    [AttributeUsage (AttributeTargets.Property, AllowMultiple=true)] 
    public sealed class PropertyComparison : BvmfBaseValidatorAttribute 
    {

        /// <summary>
        /// Tipo de comparação a ser realizada
        /// </summary>
        private ComparisonType _comparisonType;

        /// <summary>
        /// Nome da propriedade com a qual a comparação deve ser feita
        /// </summary>
        private string _propertyToCompare;

        /// <summary>
        /// Construtor, sem ruleset
        /// </summary>
        /// <param name="codException">Código de exceção a ser gerada se propriedade que recebe 
        /// este atributo for inválida</param>
        /// <param name="propertyToCompare">Nome da propriedade a ser comparada</param>
        /// <param name="comparisonType">Tipo de comparação a ser realizada</param>
        public PropertyComparison(int codException, ComparisonType comparisonType, string propertyToCompare) 
            : base(codException)
        {
            _propertyToCompare = propertyToCompare; 
            _comparisonType = comparisonType;
        }

        /// <summary>
        /// Construtor, com ruleset
        /// </summary>
        /// <param name="codException">Código de exceção a ser gerada se propriedade que recebe 
        /// este atributo for inválida</param>
        /// <param name="propertyToCompare">Nome da propriedade a ser comparada</param>
        /// <param name="comparisonType">Tipo de comparação a ser realizada</param>
        public PropertyComparison(int codException, string ruleset, ComparisonType comparisonType, string propertyToCompare) 
            : base(codException, ruleset)
        {
            _propertyToCompare = propertyToCompare;
            _comparisonType = comparisonType;
        }

        /// <summary>
        /// Método que faz a tradução entre o tipo de comparação com o qual o desenvolvedor interage 
        /// e o tipo de comparação utilizado internamente pela Enterprise Library
        /// </summary>
        /// <param name="comparisonType">Tipo de comparação informado pelo desenvolvedor</param>
        /// <returns>Tipo de comparação usado pela Enterprise Library</returns>
        private ComparisonOperator TranslateComparisonTypeToComparisonOperator(ComparisonType comparisonType)
        {
            switch (comparisonType)
            {
                case ComparisonType.Equal:
                    return ComparisonOperator.Equal;
                case ComparisonType.GreaterThan:
                    return ComparisonOperator.GreaterThan;
                case ComparisonType.GreaterThanEqual:
                    return ComparisonOperator.GreaterThanEqual;
                case ComparisonType.LessThan:
                    return ComparisonOperator.LessThan;
                case ComparisonType.LessThanEqual:
                    return ComparisonOperator.LessThanEqual;
                default:
                    return ComparisonOperator.NotEqual;
            }
        }

        /// <summary>
        /// Método de implementação requerida (abstract na classe base) que retorna 
        /// o objeto Validator a ser utilizado nesta validação
        /// </summary>
        /// <returns></returns>
        public override Microsoft.Practices.EnterpriseLibrary.Validation.Validator CreateValidator()
        {
            return new PropertyComparisonValidator(_propertyToCompare, _comparisonType); 
        }
    }
}
